package com.paas.demo.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.paas.demo.common.PPageInfo;
import com.paas.demo.dao.CommonInfoMapper;
import com.paas.demo.domain.CommonInfo;
import com.paas.demo.mybatis.mapper.UserInfoMapper;
import com.paas.demo.mybatis.model.UserInfo;
import com.paas.demo.mybatis.model.UserInfoExample;
import com.paas.demo.service.DemoService;
import com.paas.demo.service.UserInfoService;
import com.paas.demo.thrift.api.OAuthProviderService;
import com.plat.paas.core.FileUtil;
import com.plat.paas.core.KafkaUtil;
import com.plat.paas.core.MongoUtil;
import com.plat.paas.core.RedisUtil;
import io.shardingsphere.api.HintManager;
import io.shardingsphere.core.hint.HintManagerHolder;
import io.swagger.annotations.ApiOperation;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
public class HomeController {
	
	@Autowired
	DemoService demoservice;
	@Autowired
	CommonInfoMapper commonInfoMapper;
    @Autowired
	UserInfoService userInfoService;
	
    @Autowired
	UserInfoMapper userInfoMapper;
    
    @Resource(name="providerService")
    OAuthProviderService.Iface providerService;
	@Autowired
	Service service;

	public static int userId = 150;

	@ApiOperation("查询")
	@GetMapping("/home")
	public String list(@RequestParam(name= "name",required = true)String name) throws IOException{

		System.out.println(" =======================Sharding-JDBC TEST START =========================");
		

        for (int i = 1; i <= 10; i++) {
            UserInfo userInfo = new UserInfo();
            userInfo.setAccount("Account" + i);
            userInfo.setPassword("pass" + i);
            userInfo.setUserName("name" + i);
            userId++;
            if(i==3){
                HintManagerHolder.clear();
                HintManager hintManager = HintManager.getInstance();
                //hintManager.addDatabaseShardingValue("user_info", "user_id", 3L);
                //hintManager.addTableShardingValue("user_info", "user_id", 3L);
                System.out.println(userId);
            }
        }  
        for (int i = 1; i <= 10; i++) {
            CommonInfo commonInfo = new CommonInfo();
            commonInfo.setId(i);
            commonInfo.setName("name " + i);
            commonInfoMapper.insert(commonInfo);
        } 
		System.out.println(" =======================Sharding-JDBC TEST END =========================");
		
		return "hallo " + name;
	}
	@ApiOperation("分页")
	@GetMapping("/page")
	public String page(@RequestParam(name= "page",required = true)int page, @RequestParam(name= "size",required = true)int size) throws IOException{
			
		System.out.println(" =======================Sharding-JDBC TEST START =========================");
		Map<String, Object> params = new HashMap<>();
		List<Integer> ids = new ArrayList<>();
		ids.add(51);
		ids.add(46);
		ids.add(48);
		ids.add(50);
		ids.add(53);
		ids.add(49);
		params.put("user_ids", ids);
		
		
		PPageInfo<UserInfo> users = demoservice.queryForListPage(params, page, size);
		
		System.out.println("total = " + users.getTotal() + ", pages = " + users.getPages() + ", datas = " + JSON.toJSONString(users.getList()));
		
		System.out.println(" =======================Sharding-JDBC TEST END =========================");
				
		return JSON.toJSONString(users);
	}
	@ApiOperation("事務測試")
	@GetMapping("/transactions")
	public String transactions(@RequestParam(name= "page",required = true)int page, @RequestParam(name= "size",required = true)int size) throws Exception{
		
		
		System.out.println(" =======================Sharding-JDBC transactions START =========================");

		userInfoService.insertUser(null);
		
		//userInfoService.insertcommon();
		System.out.println(" =======================Sharding-JDBC transactions END =========================");
				
		return null;
	}
	
	@ApiOperation("分片字段测试")
	@GetMapping("/testselect")
	public Object testselect(@RequestParam(name= "page",required = true)int page, @RequestParam(name= "size",required = true)int size){
		
		
		System.out.println(" =======================Sharding-JDBC transactions START =========================");
		
		//Date selectDate = DateUtil.parseDate("2018-12-10 23:04:00", DateUtil.TIMESTAMP_PATTERN);
		UserInfoExample example = new UserInfoExample();		
		//example.createCriteria().andUserIdBetween(279023793651843070L, 279023793651843074L);
		//example.createCriteria().andPasswordEqualTo("password 0");
		//example.createCriteria().andCreateTimeGreaterThan(selectDate);
		example.setOrderByClause("create_time");

    	PageHelper.startPage(page, size);

		List<UserInfo> users = userInfoMapper.selectByExample(example);
		
		System.out.println("user = " + JSON.toJSONString(users));
		PPageInfo<UserInfo> pageInfo = new PPageInfo<UserInfo>(users);

		System.out.println(" =======================Sharding-JDBC transactions END =========================");
				
		return pageInfo;
	}
	@ApiOperation("redis 测试")
	@GetMapping("/testredis")
	public Object testredis() throws Exception{
		
		
		System.out.println(" =======================Redis TEST START =========================");
		for (int i = 0; i < 10; i++) {
			RedisUtil.lpush("mytestll", 1);
		}
		final CountDownLatch cdl = new CountDownLatch(1);
		
		final AtomicInteger counts = new AtomicInteger();
		final AtomicInteger start = new AtomicInteger();

		
		for (int i = 0; i < 1000; i++) {
			Thread thread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					int theadNum = start.incrementAndGet();
					try {
						System.out.println("线程 等待 ..." + theadNum);
						cdl.await();
					} catch (Exception e) {
						// TODO: handle exception
					}
					// 请求队列
					if (RedisUtil.llen("qingqiu") < 100) {
						
					}
					
					// TODO Auto-generated method stub
					if (RedisUtil.lpop("mytestll", Integer.class) != null) {
						System.out.println("线程  【"+theadNum + "】 第  "+ counts.incrementAndGet() +" 个qiang dao !");
						
						RedisUtil.lpush("qiangdao", 1);
					}
				}
			});
			thread.start();
		}
		while (start.get() < 1000) {
			Thread.sleep(1000);
		}
		System.out.println("秒杀开始 ...");
		cdl.countDown();
		
		System.out.println(" =======================Redis TEST END =========================");
				
		return null;
	}
	@ApiOperation("thrift 测试")
	@GetMapping("/thrift")
	public Object thrift() throws Exception{
		
		return providerService.getAppById("");	
	}
	@ApiOperation("kafka 测试")
	@GetMapping("/kafka")
	public Object kafka(int count) throws Exception{

		for (int i=0; i<= count; i++){
			KafkaUtil.sendMessage("this is a test kafka msg " + i, "test-topic");
		}

		return "success";	
	}
	@ApiOperation("mongodb 测试")
	@GetMapping("/mongodb")
	public Object mongodb() throws Exception{
		System.out.println(" =======================MongoDB TEST START =========================");

    	String sql = "select name from collection4 where age between 0 and 20 limit 3, 3";
    	print(MongoUtil.find("mongotest", sql));
    	
    	File file = new File("E:/demo.jpg");
    	String fileId = FileUtil.upload2GridFS(file, "plat-test.jpg");
    	String url = FileUtil.getUrl(fileId, "pdf");
    	System.out.println("fileId = " + fileId + ", url = " + url);

    	System.out.println(" =======================MongoDB TEST END =========================");

		return null;
		
	}
	@ApiOperation("upload 测试")
	@PostMapping("/upload")
	public Object upload(MultipartFile partfile) throws Exception{
		System.out.println(" =======================upload TEST START =========================");


		System.out.println("OriginalFilename = " + partfile.getOriginalFilename() + ", name = " + partfile.getName());
		String uploadUrl = tranferFile(partfile, "TEST", "E:/images", "localhost:8082/images");
		System.out.println("image url = " + uploadUrl);


		System.out.println(" =======================upload TEST END =========================");

		return "success";

	}
	@ApiOperation("DistributedLock 测试")
	@GetMapping("/distributedLock")
	public Object distributedLock() throws Exception{
		System.out.println(" =======================DistributedLock TEST START =========================");

		service.seckill2();

		System.out.println(" =======================DistributedLock TEST END =========================");

		return "success";

	}
	private String tranferFile(MultipartFile multiFile, String flag, String loaclDirPath, String domainUrl) throws IOException {
		if (multiFile == null) {
			return "";
		}

		String oriName = multiFile.getOriginalFilename();
		String fileName = flag.toUpperCase() + System.currentTimeMillis() + oriName.substring(oriName.lastIndexOf("."));
		File dirFile = new File(loaclDirPath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		File file = new File(dirFile.getPath() + "/" + fileName);
		multiFile.transferTo(file);
		return domainUrl + "/" + fileName;
	}
    private static void print(Document rec) {
        //ObjectId id = rec.getObjectId("_id");
        //System.out.println(rec.get("_id") + " name:" + rec.get("name") + " age:" + rec.get("age"));
    	String result = "";
    	for (String key : rec.keySet()) {
			result += ", " + key + " : " + rec.get(key); 
		}
        System.out.println(result);

    }
    
    private static void print(List<Document> list) {
        for (Document rec : list) {
            print(rec);
        }
    }
}
